package com.liarjo.mywebsiteapi.admin.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Base64;
import java.util.Date;
import java.util.Map;

import javax.crypto.SecretKey;

@Component
public class JwtUtil {
    @Value("${app.jwt.secret}")
    private String secret;

    @Value("${app.jwt.expiration}")
    private long expiration;

    @Value("${app.jwt.refresh_threshold}")
    private long refreshThreshold;

    public enum JwtStatus {
        TOKEN_VALID,         // 有效
        TOKEN_EXPIRED,        // 过期
        TOKEN_INVALID       // 无效
    }

    private SecretKey getSecretKey() {
        return Keys.hmacShaKeyFor(Base64.getDecoder().decode(this.secret));
    }

    // 生成 JWT
    public String generateToken(String subject, Map<String, Object> customClaims) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + this.expiration);

        return Jwts.builder()
                .setSubject(subject)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .addClaims(customClaims)
                .signWith(getSecretKey())
                .compact();
    }

    public String generateToken(String subject) {
        return generateToken(subject, null);
    }

    // 解析 JWT
    public Claims parseToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSecretKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    // 验证 JWT 是否有效
    public JwtStatus validateToken(String token) {
        try {
            parseToken(token);
        } catch (io.jsonwebtoken.ExpiredJwtException e) {
            // Token 过期
            return JwtStatus.TOKEN_EXPIRED;
        } catch (Exception e) {
            return JwtStatus.TOKEN_INVALID;
        }
        return JwtStatus.TOKEN_VALID;
    }

    // 判断是否快过期
    public boolean isTokenExpiringSoon(String token) {
        Claims claims = parseToken(token);
        Date expiration = claims.getExpiration();
        return expiration.getTime() - System.currentTimeMillis() < this.refreshThreshold;
    }

    public String refreshToken(String token) {
        JwtStatus jwtStatus = validateToken(token);
        if (jwtStatus != JwtStatus.TOKEN_VALID) {
            throw new IllegalArgumentException("Invalid refresh token");
        }

        Claims claims = parseToken(token);
        String subject = claims.getSubject();

        return generateToken(subject, claims);
    }

    public static void main(String[] args) {
        // 生成一个 32 字节的随机密钥
        byte[] keyBytes = Keys.secretKeyFor(SignatureAlgorithm.HS256).getEncoded();

        // 将密钥编码为 Base64 字符串
        String base64Key = Base64.getEncoder().encodeToString(keyBytes);

        // 输出生成的密钥
        System.out.println("Generated Key: " + base64Key);
    }
}
